package db_manager;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

/**
 * this class contains helpful functions for analyzing details from the DB's:files, dirs, users 
 */
public class Manager 
{
	static private Manager instance = null;
	//for singleton
	private static Object someObject = new Object();
	
	private Manager(){}
	
	/*making sure that there is just one instance of this class*/
	static public Manager getInstance() 
	{
		if(null == instance) 
		{
			//to insure that the time slice doesn't cause to creation of 2 instances
			synchronized (someObject) 
			{
				if (null == instance)
					instance = new Manager();
			}
		}
	    return instance;
	}	
	
	/**
	 * @param user_name is for checking if this user name is already exists in DB 'users'
	 * @param session is for connection with the DB 
	 * @return true- if this user name exists in data base,else -return false
	 */
	public boolean isUserExist(String user_name,Session session)
	{
	     Query query = session.createQuery("from db_manager.User");
	     @SuppressWarnings("unchecked")
	     List <User>list = query.list();
	     Iterator<User> it=list.iterator();
	     User user;
	     //run over all the tuples in DB 
	     while (it.hasNext())
	     {
	    	 user=it.next();
	    	 //the case the user name exists is DB
	    	 if (user.getUser_name().equals(user_name))
	    	 {
	    		 return true;
	    	 }			
	     }
	     //the case the user name doesn't exists is DB
	     return false;
	}
	
	/**
	 * the function run over all the tuples on the DB and check the maximum dir_id
	 * 				which is in use and return the (maximum+1)
	 * @param session is for connection with the DB
	 * @return a new dir_id for the next tuple 
	 */
	public long nextDirId(Session session)
	{
		 Query query = session.createQuery("from db_manager.Dir");
	     @SuppressWarnings("unchecked")
	     List <Dir>list = query.list();
	     Iterator<Dir> it=list.iterator();
	     Dir dir;
	     long max = 0;
	     //run over all the tuples in DB 
	     while (it.hasNext())
	     {
	    	 dir = it.next();
	    	 //check if this dir_id is upper then max
	    	 if (dir.getDir_id() > max)
	    	 {
	    		 max = dir.getDir_id();
	    	 }			
	     }
	     max++;
	     return max;
	}

	/**
	 * the function run over all the tuples in DB and return the user id which 
	 * 				belongs to 'user name'
	 * @param session is for connection with the DB 
	 * @param user_name is for checking the user_id to this user name
	 * @return the user_id for user_name
	 */
	public long checkUserId(Session session, String user_name)
	{
		Query query = session.createQuery("from db_manager.User");
		@SuppressWarnings("unchecked")
		List <User>list = query.list();
		Iterator<User> it=list.iterator();
		User user;
		 //run over all the tuples in DB
		while (it.hasNext())
		{
			user = it.next();
			//the case this tuple is with the user_name we search
			if (user.getUser_name().equals(user_name))
			{
				//return the user_id which belongs to 'user_name'
				return user.getUser_id();
			}			
		}
		//the case there is no user_name with this name in DB 
		return 0;
	}

	/**
	 * the function run over all the tuples in DB and return the dirId which 
	 * 				belongs to 'userName' & 'dirName'
	 * @param session is for connection with the DB 
	 * @param dirName is the dir_name in DB which we search
	 * @param userName is for finding the userId which belongs to this userName
	 * @return the dir_id which exists in the same tuple with 'dirName' & 'userId'
	 * 			in DB
	 */
	public long findDirId(Session session, String dirName, String userName) 
	{
		//checking the user id which belongs to this user name
		long userId = checkUserId(session, userName);
		Query query = session.createQuery("from db_manager.Dir");
		@SuppressWarnings("unchecked")
		List <Dir>list = query.list();
		Iterator<Dir> it = list.iterator();
		Dir dir;
		 //run over all the tuples in DB
		while (it.hasNext())
		{
			dir = it.next();
			//check if this tuple contains the userId and dirName which we want to find 
			if (dir.getUser_id() == userId && dir.getDir_name().equals(dirName))
			{
				//return the dirId in this tuple
				return dir.getDir_id();
			}			
		}
		//the case there is no tuple which contains the user id and dir id we search
		return 0;
	}

	/**
	 * @param session is for connection with the DB
	 * @param hash is for searching tuple in DB with the same hash
	 * @return true- if a file with this hash exists in one of the tuples.
	 * 			else- return false.
	 */
	public boolean wasLoaded(Session session, String hash) 
	{
		Query query = session.createQuery("from db_manager.File");
		@SuppressWarnings("unchecked")
		List <db_manager.File>list = query.list();
		Iterator<db_manager.File> it = list.iterator();
		db_manager.File file;
		//run over all the tuples in DB
		while (it.hasNext())
		{
			file = it.next();
			//the case we found a file with this hash 
			if (file.getHash().equals(hash))
			{
				return true;
			}			
		}
		//we didn't find a file with this hash
		return false;
	}
	
	/**
	 * the function run over all DB files and delete a tuple with 
	 * 				these dir_id and fileName
	 * @param dir_id is for finding a file in DB with this dir_id
	 * @param fileName is for finding a file in DB with this fileName
	 */
	public void deleteFile(long dir_id, String fileName) 
	{
		File sessionFile = new File("C:\\Program Files\\m&l_dropbox_server\\hibernate.cfg.xml");
		//creating session for connecting to DB
		SessionFactory sessionFactory = new Configuration().configure(sessionFile).buildSessionFactory();
		Session session = sessionFactory.openSession();
		String temp_hash = null;
		FileManager fm = new FileManager(session);
		Query query = session.createQuery("from db_manager.File");
		@SuppressWarnings("unchecked")
		List <db_manager.File>list = query.list();
		Iterator<db_manager.File> it=list.iterator();
		db_manager.File file;
		//run over all the tuples in DB
		while (it.hasNext())
		{
			file = it.next();
			//the case this tuple contains the dir_id and fileName
			if (file.getDir_id() == dir_id && file.getFile_name().equals(fileName))
			{
				//saving the hash of the file before deleting the tuple.
				temp_hash = file.getHash();
				//deleting the tuple from DB
				fm.deleteFile(file);
			}			
		}
		session.flush();
		Session session2 = sessionFactory.openSession();
		if (temp_hash != null)
		{
			//check if the file still exists in DB in another dir_id or with
			//another name
			boolean does_exist = wasLoaded(session2, temp_hash);
			//the case the file doesn't exist anymore therefore we want to delete it from server
			if (!does_exist)
			{
				//deleting the file from server directory
				deleteFromUploadServerFiles(temp_hash);
			}
		}
		session2.flush();
	}
	
	/**
	 * the function delete the file with the hash like 'temp_hash'
	 * 				from the server directory
	 * @param temp_hash is the hash of the file we want to delete from server
	 */
	private void deleteFromUploadServerFiles(String temp_hash)  
	{
		//open the directory in the server where the file exists
		File f = new File("C:/uploadedServerFiles");	
		String[] list = f.list();
		String str,hash = null;
		byte[] bytes;
		File file;
		//the case there are files in server directory
		if (list != null)
		{
			//run over all the files in server directory
			for (int i = 0; i < list.length; i++) 
			{
				str = list[i];
				file = new File("C:/uploadedServerFiles/"+str);
				//check the bytes of the current file
				bytes = convFileToByte(file);
				try 
				{
					//checking the hash of the current file according to the bytes
					hash = getHash(bytes);
				} 
				catch (NoSuchAlgorithmException e) 
				{
					e.printStackTrace();
				}
				//the file with temp_hash was found in server
				if (hash.equals(temp_hash))
				{
					//deleting the file
					file.delete();
				}
			}	
		}
	}
	
	/*
	 * @param file 
	 * @return the bytes of the file 
	 * @comment - this code was taken from the Internet
	 */
	public byte[] convFileToByte(File file)
	{
		FileInputStream fis = null;
		try 
		{
			fis = new FileInputStream(file);
		} 
		catch (FileNotFoundException e1) 
		{
			e1.printStackTrace();
		}
		ByteArrayOutputStream bos = new ByteArrayOutputStream();
		byte[] buf = new byte[1024];
		try 
		{
			for (int readNum; (readNum = fis.read(buf)) != -1;) 
			{
				bos.write(buf, 0, readNum); 
			}
		} 
		catch (IOException ex) {}
		byte[] bytes = bos.toByteArray();
		try 
		{
			fis.close();
			bos.flush();
			bos.close();
		} 
		catch (IOException e) 
		{
			e.printStackTrace();
		}
		return bytes;
	}
	
	/*
	 * @param bytes -is bytes of a file
	 * @return the hash of the file according to the array of bytes
	 * @throws NoSuchAlgorithmException
	 */
	private String getHash(byte[] bytes) throws NoSuchAlgorithmException
	{
		MessageDigest m = MessageDigest.getInstance("MD5");
		m.update(bytes, 0, bytes.length);
		String hash = new BigInteger(1,m.digest()).toString(16);
		return hash;
	}

	/**
	 * @param session is for connection with the DB
	 * @param dir_name is for finding the dir_id 
	 * @param user_name is for finding the tuple with this user_name
	 * @return true -if the directory exists in more then one user
	 * 			else-return false
	 */
	public boolean checkShared(Session session, String dir_name, String user_name)
	{
		//check the dir_id according to the dir name
		long dir_id = findDirId(session, dir_name, user_name);
		Query query = session.createQuery("from db_manager.Dir");
		@SuppressWarnings("unchecked")
		List <Dir>list = query.list();
		Iterator<Dir> it = list.iterator();
		Dir dir;
		//run over all the tuples in DB
		while (it.hasNext())
		{
			dir = it.next();
			//the case this tuple is with the dir_id from the input and another user from input
			if (dir.getDir_id() == dir_id && dir.getUser_id() != checkUserId(session, user_name))
			{
				//the directory is shared with more then one user
				return true;
			}			
		} 
		//this directory exists only in one user
		return false;
	}

	/**
	 * the function search a tuple with the dir_id which 
	 * 				we find according to dir_name & user_name and delete 
	 * 				this tuple from DB files
	 * @param session is for connection with the DB
	 * @param dir_name & user_name is for finding the dir_id
	 */
	public void deleteFilesFromDir(Session session, String dir_name, String user_name) 
	{
		//finding the dir_id according to dir_name and user_name 
		long dir_id = findDirId(session, dir_name, user_name);
		Query query = session.createQuery("from db_manager.File");
		@SuppressWarnings("unchecked")
		List <db_manager.File>list = query.list();
		Iterator<db_manager.File> it = list.iterator();
		db_manager.File file;
		//run over all the tuples in DB
		while (it.hasNext())
		{
			file = it.next();
			//the case this tuple have the dir_id we search
			if (file.getDir_id() == dir_id)
			{
				//deleting the tuple from DB files
				deleteFile(dir_id, file.getFile_name());
			}			
		}
		session.flush();
	}

	/**
	 * insert the files in the directory 'dir_path' to DB files if the
	 * 				directory isn't empty
	 * @param dir_path
	 * @param dir_id
	 * @return true- if there is no files in the directory 'dir_path' to insert to DB,
	 * 			else-return false 
	 */
	public boolean insertFilesInDir(String dir_path, long dir_id)
	{
		boolean empty = true;
		File f = new File(dir_path);	
		String[] list = f.list();
		File file;
		//the case there are files in the directory
		if (list != null)
		{
			//run over the files in the directory 
			for (int i = 0; i < list.length; i++) 
			{
				empty = false;
				file = new File(dir_path + "/" + list[i]);
				try 
				{
					//add a tuple to the DB files with the details of the file 
					insertFile(file, list[i], dir_id);
				}
				catch (NoSuchAlgorithmException e) 
				{
					e.printStackTrace();
				}
			}	
		}
		return empty;
	}

	/*
	 * @param the_file is the file we want to insert to DB (the details of the file)
	 * @param file_name is the name of the name of the file we want to insert to DB
	 * @param dir_id is the id of the dir where the file exists
	 * @description the function insert a tuple with the file details to DB files
	 * @throws NoSuchAlgorithmException
	 */
	private void insertFile(File the_file, String file_name, long dir_id) throws NoSuchAlgorithmException
	{
		File sessionFile = new File("C:\\Program Files\\m&l_dropbox_server\\hibernate.cfg.xml");
		//creating session for connecting to DB
		SessionFactory sessionFactory = new Configuration().configure(sessionFile).buildSessionFactory();
		Session session = sessionFactory.openSession();
		//bytes- array with the bytes of the file 
		byte[] bytes = convFileToByte(the_file);
		//the hash of the file according to the bytes
		String hash = getHash(bytes);		
		//check if the file was loaded before 
		boolean does_exist = wasLoaded(session,hash);
		
		/*these commands are for insertion file to DB*/
		FileManager fm = new FileManager(session);
		db_manager.File file = new db_manager.File();
		file.setFile_name(file_name);
		file.setDir_id(dir_id);
		file.setHash(hash);
		fm.saveFile(file);
		session.flush();
		//the case the file wasn't loaded before to the server
		if(!does_exist)
		{
			/*insertion of the file to the server directory*/
			Session session2 = sessionFactory.openSession();
			long file_id = getfile_id(session2, file);
			convByteToFile(bytes, "c:/uploadedServerFiles" + "/" + file_id);
			session2.flush();
		}
	}

	/*
	 * @param bytes is the bytes of the file we want to get
	 * @param path is the path where we want the file to be created
	 * @return the file that was created
	 * @comment this code was taken from the Internet
	 */
	private File convByteToFile(byte[] bytes, String path)
	{ 
		File newFile = new File(path);
		FileOutputStream fos = null;

		try 
		{
			fos = new FileOutputStream(newFile);
			fos.write(bytes);
			fos.flush();
			fos.close();
		}
		catch (IOException e)
		{
			e.printStackTrace();
		}      

		return newFile;
	}
	
	/**
	 * this function check if the user_name and password exists in
	 * 				DB users already 
	 * @param user_name - the user name
	 * @param password - the user password
	 * @return true- if exist a user in DB with these details.else -return false
	 */
	public boolean validateUser(String user_name,String password)
	{
		File sessionFile = new File("C:\\Program Files\\m&l_dropbox_server\\hibernate.cfg.xml");
		//creating session for connecting to DB
		SessionFactory sessionFactory = new Configuration().configure(sessionFile).buildSessionFactory();
		Session session = sessionFactory.openSession();
		Query query = session.createQuery("from db_manager.User");
		@SuppressWarnings("unchecked")
		List <User>list = query.list();
		Iterator<User> it=list.iterator();
		User user;
		//run over the tuples in DB
		while (it.hasNext())
		{
			user=it.next();
			//the case the user name and password of the tuple are suitable to the input
			if (user.getUser_name().equals(user_name) && user.getPassword().equals(password))
			{
				session.flush();
				return true;
			}			
		}
		session.flush();
		//there is no user in DB with this user name and password
		return false;
	}

	/**
	 * @param userName is the name of the user that we want his directories' names
	 * @return array list with the directories' names of the user 'userName'
	 */
	public ArrayList<String> getDirsOfUser(String userName)
	{
		File sessionFile = new File("C:\\Program Files\\m&l_dropbox_server\\hibernate.cfg.xml");
		//creating session for connecting to DB
		SessionFactory sessionFactory = new Configuration().configure(sessionFile).buildSessionFactory();
		Session session = sessionFactory.openSession();
		ArrayList<String> dirs = new ArrayList<String>();
		//finding user id according to user name
		long user_id = checkUserId(session, userName);
		Query query = session.createQuery("from db_manager.Dir");
		@SuppressWarnings("unchecked")
		List <Dir>list = query.list();
		Iterator<Dir> it = list.iterator();
		Dir dir;
		//run over all the tuples in DB 
		while (it.hasNext())
		{
			dir = it.next();
			//the case this directory belongs to the user_id
			if (dir.getUser_id() == user_id)
			{
				dirs.add(dir.getDir_name());
			}			
		}
		session.flush();
		return dirs;
	}

	/**
	 * @param dirs is list of the directories of the user 'userName'
	 * @param userName is the name of the user we want his files' names
	 * @param dirsOfFiles - the dirs numbers of the files
	 * @return list with the names of the files which exists in the directories in the list dirs
	 */
	public ArrayList<String> getFilesOfUser(ArrayList<String> dirs,String userName, ArrayList<Long> dirsOfFiles) 
	{
		File sessionFile = new File("C:\\Program Files\\m&l_dropbox_server\\hibernate.cfg.xml");
		//creating session for connecting to DB
		SessionFactory sessionFactory = new Configuration().configure(sessionFile).buildSessionFactory();
		Session session = sessionFactory.openSession();
		ArrayList<String> files = new ArrayList<String>();
		long dir_id;
		//running over the list of directories
    	for (int i = 0; i < dirs.size(); i++) 
    	{
    		//finding the dir id according to the user_name and dir_name
    		dir_id = findDirId(session, dirs.get(i), userName);
    		Query query = session.createQuery("from db_manager.File");
    		@SuppressWarnings("unchecked")
    		List <db_manager.File>list = query.list();
    		Iterator<db_manager.File> it = list.iterator();
    		db_manager.File file;
    		//running over the tuples in DB files
    		while (it.hasNext())
    		{
    			file = it.next();
    			//the case this file exists in dir_id
    			if (file.getDir_id() == dir_id)
    			{
    				files.add(file.getFile_name());
    				dirsOfFiles.add(dir_id);
    			}			
    		}
    	}
		session.flush();
		return files;
	}

	/**
	 * @param userName is the name of the user we want his files which exists in 'dirName
	 * @param dirName is the directory that we want its content
	 * @return list with the files' names that exist in the directory 'dirName'
	 */
	public ArrayList<String> findFilesInDir(String userName, String dirName) 
	{
		File sessionFile = new File("C:\\Program Files\\m&l_dropbox_server\\hibernate.cfg.xml");
		//creating session for connecting to DB
		SessionFactory sessionFactory = new Configuration().configure(sessionFile).buildSessionFactory();
		Session session = sessionFactory.openSession();
		ArrayList<String> files = new ArrayList<String>();
		//finding directori id according to directory name and user name
		long dir_id = findDirId(session, dirName, userName);
		Query query = session.createQuery("from db_manager.File");
		@SuppressWarnings("unchecked")
		List <db_manager.File>list = query.list();
		Iterator<db_manager.File> it = list.iterator();
		db_manager.File file;
		//run over the tuples in DB files 
		while (it.hasNext())
		{
			file = it.next();
			//the case this file exists in the directory with id dir_id
			if (file.getDir_id() == dir_id)
			{
				files.add(file.getFile_name());
			}			
		}
		session.flush();
		return files;
	}

	/**
	 * @param session is for connection with the DB
	 * @param file_info contains information of a tuple from DB files
	 * @return the file id of the tuple which belongs to file_info
	 */
	public long getfile_id(Session session, db_manager.File file_info)
	{
		Query query = session.createQuery("from db_manager.File");
		@SuppressWarnings("unchecked")
		List <db_manager.File>list = query.list();
		Iterator<db_manager.File> it = list.iterator();
		db_manager.File file;
		//run over the tuples in DB files 
		while (it.hasNext())
		{
			file = it.next();
			//the case the tuple in DB files is the same like the tuple which suitable to 'file_info'
			if (file.getDir_id() == file_info.getDir_id() && file.getHash().equals(file_info.getHash()) 
					&& file.getFile_name().equals(file_info.getFile_name()))
			{
				return file.getFile_id();
			}			
		}
		//the case we didn't find tuple which suitable to file_info
		return 0;
	}

	/**
	 * this function insert the new directory we share to the DB dirs
	 * @param oldUserName is the name of the user that is using the web interface 
	 * @param dirName is the dir we want to share
	 * @param current_user_id is the user we want to share with
	 */
	public void share_dir(String oldUserName, String dirName, long current_user_id)
	{
		File sessionFile = new File("C:\\Program Files\\m&l_dropbox_server\\hibernate.cfg.xml");
		//creating session for connecting to DB
		SessionFactory sessionFactory = new Configuration().configure(sessionFile).buildSessionFactory();
		Session session = sessionFactory.openSession();
		//dir- is the directory which oldUserName wants to share with the user which belongs to current_user_id
		Dir dir = findDir(session, dirName, oldUserName);
		if(dir != null)
		{
			/*all these commands are for inserting this directory to DB dirs*/
			DirManager dm = new DirManager(session);
			Dir shared_dir = new Dir();
			shared_dir.setDir_name(dirName);
			shared_dir.setUser_id(current_user_id);
			shared_dir.setDir_id(dir.getDir_id());
			dm.saveDir(shared_dir);
		}
		session.flush();
	}
	
	/**
	 * @param session is for connection with the DB
	 * @param dirName - the name of the dir we want to find
	 * @param userName - the name of the user this dir belongs to
	 * @return the dir we searched for
	 */
	public Dir findDir(Session session, String dirName, String userName) 
	{
		// getting the user id
		long userId = checkUserId(session, userName);
		Query query = session.createQuery("from db_manager.Dir");
		@SuppressWarnings("unchecked")
		List <Dir>list = query.list();
		Iterator<Dir> it = list.iterator();
		Dir dir;
		//run over the tuples in DB dirs
		while (it.hasNext())
		{
			dir = it.next();
			//the case the tuple in DB dirs is the same like the tuple which suitable to the given parameters
			if (dir.getUser_id() == userId && dir.getDir_name().equals(dirName))
			{
				return dir;
			}			
		}
		return null;
	}
	
	/**
	 * @param session is for connection with the DB
	 * @param dir_id
	 * @param file_names - the array of files name in the dir
	 * @return the array of hashes of files  in the dir
	 */
	public ArrayList<String> findHashesInDir(Session session, long dir_id, ArrayList<String> file_names) 
	{
		ArrayList<String> hashes = new ArrayList<String>();
		Query query = session.createQuery("from db_manager.File");
		@SuppressWarnings("unchecked")
		List <db_manager.File>list = query.list();
		Iterator<db_manager.File> it = list.iterator();
		db_manager.File file;
		//run over the tuples in DB files
		while (it.hasNext())
		{
			file = it.next();
			//the case the tuple in DB files is the same like the tuple which suitable to the given parameters
			if (file.getDir_id() == dir_id)
			{
				hashes.add(file.getHash());
				file_names.add(file.getFile_name());
			}			
		}
		return hashes;
	}
	
	/**
	 * @param temp_hash - the hash we search for
	 * @return the bytes of the file we searched (null if not found)
	 */
	public byte[] findFileFromUploadServerFiles(String temp_hash) 
	{
		File f = new File("C:/uploadedServerFiles");
		// getting the dir content
		String[] list = f.list();
		String str,hash = null;
		byte[] bytes = null;
		File file;
		// the case that this dir is not empty
		if (list != null)
		{
			// for each file in dir
			for (int i = 0; i < list.length; i++) 
			{
				str = list[i];
				file = new File("C:/uploadedServerFiles/"+str);
				// getting the file byte
				bytes = convFileToByte(file);
				try 
				{
					hash = getHash(bytes);
				} 
				catch (NoSuchAlgorithmException e) 
				{
					e.printStackTrace();
				}
				// the case that this is the correct file
				if (hash.equals(temp_hash))
				{
					return bytes;
				}
			}	
		}
		return bytes;
	}

	/**
	 * @param session is for connection with the DB
	 * @param dirName - the shared dir name
	 * @param userName - the user who have the dir name
	 * @return - an array of users id's that share this dir 
	 */
	public ArrayList<Long> getSharedUsers(Session session, String dirName, String userName) 
	{
		ArrayList<Long> users_id = new ArrayList<Long>();
		long dir_id = findDirId(session, dirName, userName);
		Query query = session.createQuery("from db_manager.Dir");
		@SuppressWarnings("unchecked")
		List <Dir>list = query.list();
		Iterator<Dir> it = list.iterator();
		Dir dir;
		//run over the tuples in DB dirs
		while (it.hasNext())
		{
			dir = it.next();
			//the case the tuple in DB dirs is the same like the tuple which suitable to the given parameters
			if (dir.getDir_id() == dir_id && dir.getUser_id() != checkUserId(session, userName))
			{
				users_id.add(dir.getUser_id());
			}			
		}
		return users_id;
	}

	/**
	 * this function return a file from the uploaded server files dir with this parameter details 
	 * @param fileName - the file name
	 * @param dir_id - the file's dir id
	 * @return the correct file from the server files
	 */
	public File getTheFile(String fileName, long dir_id) 
	{
		// the case that the information is not proper
		if(fileName.equals("") || dir_id == 0)
		{
			File f = new File("");
			return f;
		}
		// the case that the information is proper
		else
		{
			File sessionFile = new File("C:\\Program Files\\m&l_dropbox_server\\hibernate.cfg.xml");
			//creating session for connecting to DB
			SessionFactory sessionFactory = new Configuration().configure(sessionFile).buildSessionFactory();
			Session session = sessionFactory.openSession();
			Query query = session.createQuery("from db_manager.File");
			@SuppressWarnings("unchecked")
			List <db_manager.File>list = query.list();
			Iterator<db_manager.File> it = list.iterator();
			db_manager.File file;
			String temp_hash = null;
			//run over the tuples in DB files 
			while (it.hasNext())
			{
				file = it.next();
				//the case this file exists in the directory with id dir_id
				if (file.getDir_id() == dir_id && file.getFile_name().equals(fileName))
				{
					temp_hash = file.getHash();
				}			
			}
			session.flush();
			// the case that the file was found in the DB
			if(temp_hash != null)
			{
				String name = findFileNameFromUploadServerFiles(temp_hash);
				// the case that the file was found in the uploadedServerFiles dir
				if(name != null)
				{
					File f = new File("C:/uploadedServerFiles/"+name);
					return f;
				}
				// the case that the file wasn't found in the uploadedServerFiles dir
				else
				{
					File f = new File("");
					return f;
				}
			}
			// the case that the file was not found in the DB
			else
			{
				File f = new File("");
				return f;
			}
		}
	}
	
	/**
	 * @param temp_hash - the hash we search for
	 * @return the name of the file we searched (null if not found)
	 */
	public String findFileNameFromUploadServerFiles(String temp_hash) 
	{
		File f = new File("C:/uploadedServerFiles");
		// getting the dir content
		String[] list = f.list();
		String str,hash = null;
		byte[] bytes = null;
		File file;
		// the case that this dir is not empty
		if (list != null)
		{
			// for each file in dir
			for (int i = 0; i < list.length; i++) 
			{
				str = list[i];
				file = new File("C:/uploadedServerFiles/"+str);
				// getting the file byte
				bytes = convFileToByte(file);
				try 
				{
					hash = getHash(bytes);
				} 
				catch (NoSuchAlgorithmException e) {}
				// the case that this is the correct file
				if (hash.equals(temp_hash))
				{
					return str;
				}
			}	
		}
		return null;
	}
}
